/**
 * Project Name:ldasp
 * File Name:ExtArrayList.java
 * Package Name:com.troy.ldc.ldasp
 * Date:2017年4月9日下午7:38:24
 * Copyright (c) 2017, chenzhou1025@126.com All Rights Reserved.
 *
*/

package jbase.project.system.core.support;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.UnaryOperator;
import java.util.stream.Stream;

public class ExtArrayList<E> implements ExtList<E> {

	private List<E> list;

	public ExtArrayList() {
		this.list = new ArrayList<E>();
	}

	public ExtArrayList(List<E> list) {
		this.list = list;
	}

	public ExtArrayList(E... array) {
		this.list = Arrays.asList(array);
	}

	public void forEach(Consumer<? super E> action) {
		list.forEach(action);
	}

	public int size() {
		return list.size();
	}

	public boolean isEmpty() {
		return list.isEmpty();
	}

	public boolean contains(Object o) {
		return list.contains(o);
	}

	public Iterator<E> iterator() {
		return list.iterator();
	}

	public Object[] toArray() {
		return list.toArray();
	}

	public <T> T[] toArray(T[] a) {
		return list.toArray(a);
	}

	public boolean add(E e) {
		return list.add(e);
	}

	public boolean remove(Object o) {
		return list.remove(o);
	}

	public boolean containsAll(Collection<?> c) {
		return list.containsAll(c);
	}

	public boolean addAll(Collection<? extends E> c) {
		return list.addAll(c);
	}

	public boolean addAll(int index, Collection<? extends E> c) {
		return list.addAll(index, c);
	}

	public boolean removeAll(Collection<?> c) {
		return list.removeAll(c);
	}

	public boolean retainAll(Collection<?> c) {
		return list.retainAll(c);
	}

	public void replaceAll(UnaryOperator<E> operator) {
		list.replaceAll(operator);
	}

	public boolean removeIf(Predicate<? super E> filter) {
		return list.removeIf(filter);
	}

	public void sort(Comparator<? super E> c) {
		list.sort(c);
	}

	public void clear() {
		list.clear();
	}

	public boolean equals(Object o) {
		return list.equals(o);
	}

	public int hashCode() {
		return list.hashCode();
	}

	public E get(int index) {
		return list.get(index);
	}

	public E set(int index, E element) {
		return list.set(index, element);
	}

	public void add(int index, E element) {
		list.add(index, element);
	}

	public Stream<E> stream() {
		return list.stream();
	}

	public E remove(int index) {
		return list.remove(index);
	}

	public Stream<E> parallelStream() {
		return list.parallelStream();
	}

	public int indexOf(Object o) {
		return list.indexOf(o);
	}

	public int lastIndexOf(Object o) {
		return list.lastIndexOf(o);
	}

	public ListIterator<E> listIterator() {
		return list.listIterator();
	}

	public ListIterator<E> listIterator(int index) {
		return list.listIterator(index);
	}

	public List<E> subList(int fromIndex, int toIndex) {
		return list.subList(fromIndex, toIndex);
	}

	public Spliterator<E> spliterator() {
		return list.spliterator();
	}

	@Override
	public <T> ExtList<T> map(Function<E, T> function) throws Exception {
		int size = this.size();
		List<T> rs = new ArrayList<T>();
		for (int i = 0; i < size; i++) {
			rs.add(function.apply(get(i)));
		}
		return new ExtArrayList<T>(rs);
	}

	@Override
	public <T> ExtList<T> flatMap(Function<E, ExtList<T>> function) throws Exception {
		int size = this.size();
		List<T> rs = new ArrayList<T>();
		for (int i = 0; i < size; i++) {
			rs.addAll(function.apply(get(i)));
		}
		return new ExtArrayList<T>(rs);
	}

	@Override
	public ExtList<E> filter(Function<E, Boolean> function) throws Exception {
		int size = this.size();
		List<E> rs = new ArrayList<E>();
		for (int i = 0; i < size; i++) {
			if (function.apply(get(i))) {
				rs.add(get(i));
			}
		}
		return new ExtArrayList<E>(rs);
	}

	@Override
	public ExtList<E> drop(int n) {
		int size = size();
		List<E> r = new ArrayList<E>();
		for (int i = 0; i < size; i++) {
			if (i >= n) {
				r.add(get(i));
			}
		}
		return new ExtArrayList<E>(r);
	}

	@Override
	public ExtList<E> excludeLast() {
		int size = size();
		List<E> r = new ArrayList<E>();
		for (int i = 0; i < size - 1; i++) {
			r.add(get(i));
		}
		return new ExtArrayList<E>(r);
	}

	@Override
	public E lastElement() {
		int size = size();
		return size > 0 ? get(size - 1) : null;
	}

}
